﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;

namespace Dude.MLS
{
    [Category("Localization")]
    [Localizable(false)] // it's localized outside of IDE
    [Serializable]
    public class MLString : List<LocaleStringPair>
    {
        private String currentText = null;

        /// <summary>
        /// Default constructor. Create empty instatnce
        /// </summary>
        public MLString()
        {
        }

        /// <summary>
        /// Create instance filled with only default localized text.
        /// If text in another languages will be added, this has lowest priority
        /// </summary>
        /// <param name="text">Default text</param>
        public MLString(string text)
        {
            base.Add(new LocaleStringPair(text));
        }

        /// <summary>
        /// Create instance filled with only one language.
        /// </summary>
        /// <param name="lang">Language code (en, de, ...)</param>
        /// <param name="text">Localized text</param>
        public MLString(string lang, string text)
        {
            Add(lang, text);
        }

        /// <summary>
        /// Add new locale-language pair
        /// </summary>
        /// <param name="lang"></param>
        /// <param name="text"></param>
        public void Add(string lang, string text)
        {
            base.Add(new LocaleStringPair(lang, text));
            currentText = null;
        }

        /// <summary>
        /// Get localized text in current language
        /// </summary>
        /// <returns>Localized text</returns>
        public override string ToString()
        {
            return currentText ?? GetLocale(Lang.currentLang);
        }

        /// <summary>
        /// Get text in selected locale. If locale is not found, 
        /// best-fit locale is selected by Lang.LocalePriority 
        /// </summary>
        /// <param name="lang">language code (en, de, ...)</param>
        /// <returns>String in selected locale</returns>
        public string GetLocale(string lang)
        {
            if (lang == Lang.currentLang)
            {
                if (currentText == null)
                {
                    currentText = FindLocale(lang) ?? FindBestLocale();
                }
                return currentText;
            }
            else
            {
                return FindLocale(lang) ?? FindBestLocale();
            }
        }

        public bool HasLocale(string locale)
        {
            return (FindLocale(locale) != null);
        }

        private string FindBestLocale()
        {
            if (this.Count == 0) return "";
            if (this.Count == 1) return this[0].Text;

            string result;
            foreach (string locale in Lang.localePriority)
            {
                result = FindLocale(locale);
                if (result != null) return result;
            }
            result = FindLocale(null);
            return result ?? "";
        }

        private string FindLocale(string lang)
        {
            foreach (LocaleStringPair pair in this)
            {
                if (lang == pair.Language) return pair.Text;
            }
            return null;
        }

        /// <summary>
        /// Get text in current language. Read only.
        /// </summary>
        public string Text
        {
            get
            {
                return ToString();
            }
        }
    }
}
